package bar.dark.lee.alarm.query;

import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.util.ArrayList;

import bar.dark.lee.alarm.common.DBSQLite;
import bar.dark.lee.alarm.sound.SoundData;
import bar.dark.lee.alarm.sound.SoundFolderData;
import bar.dark.lee.alarm.sound.SoundLowData;
import android.content.Context;
import android.database.Cursor;
import android.media.RingtoneManager;
import android.os.Environment;

/**
 * 디비에 있는 내용을 가져오는 쿼리를 관리하는 부분
 * @author darkwlstn
 *
 */
public class DBQuery
{
	private Context context;
	private DBSQLite sql;
	
	public static final String ALARMDATA = "alarmData";
	
	public DBQuery(Context context)
	{
		this.context = context;
		
		if (sql == null)
		{
			sql = DBSQLite.getInstance(context);
		}
	}
	
	/**
	 * 알람 테이블의 리스트를 가져온다.
	 * @return
	 */
	public ArrayList<AlarmData> getAlarmList(Context context)
	{
		ArrayList<AlarmData> list = new ArrayList<AlarmData>();
		
		Cursor c = null;
		
		try
		{
			c = sql.select(context, "SELECT * FROM alarm;");
			
			int idIdx = c.getColumnIndex("id"); // 아이디
			int timeIdx = c.getColumnIndex("time"); // 알람이 울리는 시간 HHMMSS 타입
			int effectIdx = c.getColumnIndex("effect"); // 효과번호
			int soundIdx = c.getColumnIndex("sound"); // sound 파일 주소
			int dateIdx = c.getColumnIndex("date"); // 알람이 울리는 요일 0:안울림 1:일요일 7:토요일
			int snoozeminuteIdx = c.getColumnIndex("snoozeminute"); // 다시 울림 간격 분
			int memoIdx = c.getColumnIndex("memo"); // 메모내용 
			int soundNameIdx = c.getColumnIndex("soundname"); // 사운드 파일이름
			int effectNameIdx = c.getColumnIndex("effectname"); // 효과 이름
			int dateNameIdx = c.getColumnIndex("datename"); // 요일 설정 이름
			int snoozeminuteNameIdx = c.getColumnIndex("snoozeminutename"); // 반복 설정 이름
			int timeNameIdx = c.getColumnIndex("timename"); //시간 설정 이름
			
			c.moveToFirst();
			
			for (int i = 0; i < c.getCount(); i++)
			{
				AlarmData data = new AlarmData();
				data.setId(c.getInt(idIdx) + "");
				data.setTime(c.getString(timeIdx));
				data.setEffect(c.getString(effectIdx)+ "");
				data.setSound(c.getString(soundIdx));
				data.setDate(c.getString(dateIdx));
				data.setSnoozeminute(c.getString(snoozeminuteIdx) + "");
				data.setMemo(c.getString(memoIdx));
				data.setSoundName(c.getString(soundNameIdx));
				data.setEffectName(c.getString(effectNameIdx));
				data.setDateName(c.getString(dateNameIdx));
				data.setSnoozeminuteName(c.getString(snoozeminuteNameIdx));
				data.setTimeName(c.getString(timeNameIdx));
				
				list.add(data);
				
				c.moveToNext();
			}
		} catch (Exception e)
		{
			e.printStackTrace();
			return list;
		} finally {
			if (c != null)
			{
				c.close();
			}
		}
		
		return list;
	}
	
	/**
	 * 알람 테이블에서 특정 아이디로 가져온다.
	 * @param id
	 * @return
	 */
	public AlarmData getAlarmData(Context context, String id)
	{
		AlarmData data = new AlarmData();
		
		Cursor c = null;
		
		try
		{
			c = sql.select(context, "SELECT * FROM alarm WHERE id = " + id + ";");
			
			int idIdx = c.getColumnIndex("id"); // 아이디
			int timeIdx = c.getColumnIndex("time"); // 알람이 울리는 시간 HHMMSS 타입
			int effectIdx = c.getColumnIndex("effect"); // 효과번호
			int soundIdx = c.getColumnIndex("sound"); // sound 파일 주소
			int dateIdx = c.getColumnIndex("date"); // 알람이 울리는 요일 0:안울림 1:일요일 7:토요일
			int snoozeminuteIdx = c.getColumnIndex("snoozeminute"); // 다시 울림 간격 분
			int memoIdx = c.getColumnIndex("memo"); // 메모내용 
			int soundNameIdx = c.getColumnIndex("soundname"); // 사운드 파일이름
			int effectNameIdx = c.getColumnIndex("effectname"); // 효과 이름
			int dateNameIdx = c.getColumnIndex("datename"); // 요일 설정 이름
			int snoozeminuteNameIdx = c.getColumnIndex("snoozeminutename"); // 반복 설정 이름
			int timeNameIdx = c.getColumnIndex("timename"); //시간 설정 이름
			
			c.moveToFirst();
			
			for (int i = 0; i < c.getCount(); i++)
			{
				data.setId(c.getInt(idIdx) + "");
				data.setTime(c.getString(timeIdx));
				data.setEffect(c.getString(effectIdx)+ "");
				data.setSound(c.getString(soundIdx));
				data.setDate(c.getString(dateIdx));
				data.setSnoozeminute(c.getString(snoozeminuteIdx) + "");
				data.setMemo(c.getString(memoIdx));
				data.setSoundName(c.getString(soundNameIdx));
				data.setEffectName(c.getString(effectNameIdx));
				data.setDateName(c.getString(dateNameIdx));
				data.setSnoozeminuteName(c.getString(snoozeminuteNameIdx));
				data.setTimeName(c.getString(timeNameIdx));
				
				c.moveToNext();
			}
		} catch (Exception e)
		{
			e.printStackTrace();
			return data;
		} finally {
			if (c != null)
			{
				c.close();
			}
		}
		
		return data;
	}
	
	/**
	 * 알람 테이블에서 제일 아이디가 큰 값을 가져온다.
	 * @return id;
	 */
	public int getAlarmDataMax(Context context)
	{
		Cursor c = null;
		
		int id = -1;
		
		try
		{
			c = sql.select(context, "SELECT max(id) maxid FROM alarm;");
			
			int idIdx = c.getColumnIndex("maxid"); // 아이디
			
			c.moveToFirst();
			
			for (int i = 0; i < c.getCount(); i++)
			{
				id = c.getInt(idIdx);
				
				c.moveToNext();
			}
		} catch (Exception e)
		{
			e.printStackTrace();
			return -1;
		} finally {
			if (c != null)
			{
				c.close();
			}
		}
		
		return id;
	}
	
	/**
	 * 음악폴더 테이블의 데이터를 가져온다.
	 * @return
	 */
	public ArrayList<SoundLocationData> getSoundLocationData(Context context)
	{
		ArrayList<SoundLocationData> list = new ArrayList<SoundLocationData>();
		
		Cursor c = null;
		
		try
		{
			c = sql.select(context, "SELECT * FROM sound_location;");
			
			int idIdx = c.getColumnIndex("id");
			int pathIdx = c.getColumnIndex("path");
			
			c.moveToFirst();
			
			for (int i = 0; i < c.getCount(); i++)
			{
				SoundLocationData data = new SoundLocationData();
				
				data.setId(c.getInt(idIdx) + "");
				data.setLocation(c.getString(pathIdx));
				list.add(data);
				c.moveToNext();
			}
		} catch (Exception e)
		{
			e.printStackTrace();
			return list;
		} finally {
			if (c != null)
			{
				c.close();
			}
		}
		
		return list;
	}
	
	public ArrayList<SoundData> getAlarmSound(Context context)
	{
		ArrayList<SoundData> list = new ArrayList<SoundData>();
		
		ArrayList<SoundLocationData> soundList = getSoundLocationData(context);
		
		for (int i = 0; i < soundList.size(); i++)
		{
			File [] files = getMp3ReadFile(soundList.get(i).getLocation());
			
			for (int j = 0; j < files.length; j++)
			{
				SoundData data = new SoundData();
				data.setFileName(files[j].getName());
				data.setFileLocation(files[j].getPath());
				list.add(data);
			}
		}
		
		RingtoneManager rm = new RingtoneManager(context);
		rm.setType(RingtoneManager.TYPE_RINGTONE);
		Cursor c = rm.getCursor();
		
		c.moveToFirst();
		
		for (int i = 0; i < c.getCount(); i++)
		{
			SoundData data = new SoundData();
			
			data.setFileName(c.getString(RingtoneManager.TITLE_COLUMN_INDEX));
			
			String path = c.getString(RingtoneManager.URI_COLUMN_INDEX) + "/";
			path += c.getString(RingtoneManager.ID_COLUMN_INDEX);
			
			data.setFileLocation(path);
			
			list.add(data);
			c.moveToNext();
		}
		
		c.close();
		
		return list;
	}
	
	/**
	 * sd 카드에 있는 mp3 파일을 전부 가져온다.
	 * @return
	 */
	public ArrayList<SoundData> getSound()
	{
		ArrayList<SoundData> list = new ArrayList<SoundData>();
		ArrayList<String> directoryList = new ArrayList<String>();
		
		try
		{
			getDirectoryList(directoryList, Environment.getExternalStorageDirectory() + "");
			
			for (int i = 0; i < directoryList.size(); i++)
			{
				File [] readFiles = getMp3ReadFile(directoryList.get(i));
				
				for (int j = 0; j < readFiles.length; j++)
				{
					File file = readFiles[j];
					SoundData data = new SoundData();
					data.setFileName(file.getName());
					data.setFileLocation(file.getPath());
					list.add(data);
				}
			}
		} catch (Exception e)
		{
			e.printStackTrace();
			return list;
		} 
		
		return list;
	}

	private void getDirectoryList(ArrayList<String> directoryList, String name)
	{
		File [] readDirectory = getReadDirectory(name);
		
		if (readDirectory == null)
		{
			return;
		}
		
		if (readDirectory.length > 0)
		{
			for (int i = 0; i < readDirectory.length; i++)
			{
				directoryList.add(readDirectory[i].getPath());
				
				getDirectoryList(directoryList, readDirectory[i].getPath());
			}
		}
		else
		{
			return;
		}
	}
	
	/**
	 * 폴더의 하위 폴더 목록을 가져온다.
	 * @param folderPath
	 * @return
	 */
	public SoundFolderData getFolderData(String folderPath)
	{
		SoundFolderData data = new SoundFolderData();
		
		File file = new File(folderPath);
		
		data.setFolderName(file.getName());
		data.setFolderPath(file.getPath());
		
		File [] files = getReadDirectory(folderPath);
		
		ArrayList<SoundLowData> lowDatas = data.getLowFolders();
		
		SoundLowData lowFirstData = new SoundLowData();
		lowFirstData.setFolderName("/..");
		lowFirstData.setFolderPath("");
		lowFirstData.setFolderAndFile(2);
		lowDatas.add(lowFirstData);
		
		for (int i = 0; i < files.length; i++)
		{
			SoundLowData lowData = new SoundLowData();
			lowData.setFolderName(files[i].getName());
			lowData.setFolderPath(files[i].getPath());
			lowData.setFolderAndFile(0);
			lowDatas.add(lowData);
		}
		
		return data;
	}
	
	/**
	 * 디렉토리의 하위 디렉토리 가져오기
	 * @param directoryPath
	 * @return	
	 */
	public File [] getReadDirectory(String directoryPath)
	{
		File directory = new File(directoryPath);
		
		File [] readFiles = directory.listFiles(new FileFilter()
		{
			@Override
			public boolean accept(File pathname)
			{
				return pathname.isDirectory();
			}
		});
		
		return readFiles;
	}
	
	/**
	 * 그 폴더의 mp3 파일 목록을 가져온다.
	 * @param data
	 * @param folderPath
	 * @return
	 */
	public SoundFolderData getMp3Data(SoundFolderData data, String folderPath)
	{
		File [] files = getMp3ReadFile(folderPath);
		
		ArrayList<SoundLowData> lowDatas = data.getLowFolders();
		
		for (int i = 0; i < files.length; i++)
		{
			SoundLowData lowData = new SoundLowData();
			lowData.setFolderName(files[i].getName());
			lowData.setFolderPath(files[i].getPath());
			lowData.setFolderAndFile(1);
			lowDatas.add(lowData);
		}
		
		return data;
	}
	
	/**
	 * 디렉토리의  mp3 파일을 가져온다.
	 * @param directoryName
	 * @return
	 */
	private File [] getMp3ReadFile(String directoryName)
	{
		File directory = new File(directoryName);
		
		File [] readFiles = directory.listFiles(new FilenameFilter()
		{
			@Override
			public boolean accept(File dir, String filename)
			{
				return (filename.endsWith(".mp3"));
			}
		});
		
		return readFiles;
	}
}
